home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
- #include <string.h>
- #include "statetbl.h"
- #include "xutil.h"
- #include "lutil.h"
- #include "ttyio.h"
- #include "session.h"
- #include "ftscprod.h"
- #include "config.h"
- #include "ftn.h"
- #include "emsi.h"
- #include "nodelist.h"
-
- #define PRODCODE 0xfe
-
- /*------------------------------------------------------------------------*/
- /* YOOHOO<tm> CAPABILITY VALUES */
- /*------------------------------------------------------------------------*/
- #define Y_DIETIFNA 0x0001 /* Can do fast "FTS-0001" 0000 0000 0000 0001 */
- #define FTB_USER 0x0002 /* Full-Tilt Boogie 0000 0000 0000 0010 */
- #define ZED_ZIPPER 0x0004 /* Does ZModem, 1K blocks 0000 0000 0000 0100 */
- #define ZED_ZAPPER 0x0008 /* Can do ZModem variant 0000 0000 0000 1000 */
- #define DOES_IANUS 0x0010 /* Can do Janus 0000 0000 0001 0000 */
- #define Bit_5 0x0020 /* reserved by FTSC 0000 0000 0010 0000 */
- #define Bit_6 0x0040 /* reserved by FTSC 0000 0000 0100 0000 */
- #define Bit_7 0x0080 /* reserved by FTSC 0000 0000 1000 0000 */
- #define Bit_8 0x0100 /* reserved by FTSC 0000 0001 0000 0000 */
- #define Bit_9 0x0200 /* reserved by FTSC 0000 0010 0000 0000 */
- #define Bit_a 0x0400 /* reserved by FTSC 0000 0100 0000 0000 */
- #define Bit_b 0x0800 /* reserved by FTSC 0000 1000 0000 0000 */
- #define Bit_c 0x1000 /* reserved by FTSC 0001 0000 0000 0000 */
- #define Bit_d 0x2000 /* reserved by FTSC 0010 0000 0000 0000 */
- #define Bit_e 0x4000 /* reserved by FTSC 0100 0000 0000 0000 */
- #define WZ_FREQ 0x8000 /* WZ file req. ok 1000 0000 0000 0000 */
-
- #define LOCALCAPS (Y_DIETIFNA|ZED_ZIPPER|ZED_ZAPPER)
-
- extern unsigned short crc16(char*,int);
- extern char *version;
- extern int janus(void);
- extern int rxwazoo(void);
- extern int txwazoo(void);
- extern int rxdietifna(void);
- extern int txdietifna(void);
- extern void rdoptions(node*);
- extern int nodelock(faddr*);
-
- static int rxyoohoo(void);
- static int txyoohoo(void);
- static void fillhello(unsigned short,char*);
- static void checkhello(void);
-
- static int iscaller;
- static struct _hello {
- unsigned char data[128];
- unsigned char crc[2];
- } hello;
-
- int rx_yoohoo(void)
- {
- int rc;
- unsigned short capabilities,localcaps;
- char *pwd;
- fa_list *tmp;
- node *nlent;
-
- loginf("start inbound WaZOO session");
-
- pwd=NULL;
- localcaps=LOCALCAPS;
- if (localoptions & NOZMODEM) localcaps &= ~(ZED_ZAPPER|ZED_ZIPPER);
- if (localoptions & NOZEDZAP) localcaps &= ~ZED_ZAPPER;
- if (localoptions & NOJANUS) localcaps &= ~DOES_IANUS;
- emsi_local_opts=0;
- emsi_remote_opts=0;
- iscaller=0;
- if ((rc=rxyoohoo()) == 0)
- {
- checkhello();
- capabilities=hello.data[114]+(hello.data[115]<<8);
- if (capabilities & WZ_FREQ) session_flags |= SESSION_WAZOO;
- else session_flags &= ~SESSION_WAZOO;
- localcaps&=capabilities;
- if (localcaps & DOES_IANUS) localcaps &= DOES_IANUS;
- else if (localcaps & ZED_ZAPPER) localcaps &= ZED_ZAPPER;
- else if (localcaps & ZED_ZIPPER) localcaps &= ZED_ZIPPER;
- else if (localcaps & FTB_USER) localcaps &= FTB_USER;
- else if (localcaps & Y_DIETIFNA) localcaps &= Y_DIETIFNA;
- if ((localoptions & NOFREQS) == 0) localcaps |= WZ_FREQ;
- else emsi_local_opts |= NRQ;
-
- if (((nlent=getnlent(remote->addr))) &&
- (nlent->pflag != DUMMY))
- {
- loginf("remote is a listed system");
- inbound=listinbound;
- rdoptions(nlent);
- }
-
- for (tmp=pwlist;tmp;tmp=tmp->next)
- if (metric(remote->addr,tmp->addr) == 0)
- {
- if (strncasecmp((char*)hello.data+98,tmp->addr->name,8) != 0)
- {
- pwd="BAD_PASS";
- loginf("remote gave password \"%s\", expected \"%s\"",
- (char*)hello.data+98,tmp->addr->name);
- localcaps=0;
- }
- else /* password did match, return it back */
- {
- loginf("remote gave correct password, protected WaZOO session");
- inbound=protinbound;
- pwd=tmp->addr->name;
- break;
- }
- }
-
- fillhello(localcaps,pwd);
-
- rc=txyoohoo();
- }
- if ((rc == 0) && ((localcaps & LOCALCAPS) == 0))
- {
- loginf("No common WaZOO protocols or bad password");
- return 0;
- }
- if (rc) return rc;
- session_flags |= SESSION_WAZOO;
- if (localcaps & DOES_IANUS) return janus();
- else if ((localcaps & ZED_ZAPPER) || (localcaps & ZED_ZIPPER))
- {
- if (localcaps & ZED_ZAPPER) emsi_local_protos=ZAP;
- else emsi_local_protos=ZMO;
- return rxwazoo();
- }
- else if (localcaps & Y_DIETIFNA) return rxdietifna();
- else logerr("WaZOO internal error - no proto for 0x%04xh",localcaps);
- return 1;
- }
-
- int tx_yoohoo(void)
- {
- int rc;
- unsigned short capabilities;
- char *pwd;
- fa_list *tmp;
-
- loginf("start outbound WaZOO session");
-
- pwd=NULL;
- for (tmp=pwlist;tmp;tmp=tmp->next)
- if (metric(remote->addr,tmp->addr) == 0)
- {
- pwd=remote->addr->name;
- break;
- }
- capabilities=LOCALCAPS;
- if (localoptions & NOZMODEM) capabilities &= ~(ZED_ZAPPER|ZED_ZIPPER);
- if (localoptions & NOZEDZAP) capabilities &= ~ZED_ZAPPER;
- if (localoptions & NOJANUS) capabilities &= ~DOES_IANUS;
- if ((localoptions & NOFREQS) == 0) capabilities |= WZ_FREQ;
- else emsi_local_opts |= NRQ;
- fillhello(capabilities,pwd);
- iscaller=1;
- if ((rc=txyoohoo()) == 0)
- {
- rc=rxyoohoo();
- checkhello();
- capabilities=hello.data[114]+(hello.data[115]<<8);
- if (capabilities & WZ_FREQ) session_flags |= SESSION_WAZOO;
- else session_flags &= ~SESSION_WAZOO;
- }
- if ((rc == 0) && ((capabilities & LOCALCAPS) == 0))
- {
- loginf("No common WaZOO protocols");
- return 0;
- }
- if (rc) return rc;
- session_flags |= SESSION_WAZOO;
- if (capabilities & DOES_IANUS) return janus();
- else if ((capabilities & ZED_ZAPPER) || (capabilities & ZED_ZIPPER))
- {
- if (capabilities & ZED_ZAPPER) emsi_local_protos=ZAP;
- else emsi_local_protos=ZMO;
- return txwazoo();
- }
- else if (capabilities & Y_DIETIFNA) return txdietifna();
- else logerr("WaZOO internal error - no proto for 0x%04xh",capabilities);
- return 1;
- }
-
- SM_DECL(rxyoohoo,"rxyoohoo")
- SM_STATES
- sendenq,waitchar,getpacket,sendnak,sendack
- SM_NAMES
- "sendenq","waitchar","getpacket","sendnak","sendack"
- SM_EDECL
-
- int c;
- int count=0;
- unsigned short lcrc,rcrc;
-
- SM_START(sendenq)
-
- SM_STATE(sendenq)
-
- if (count++ > 9)
- {
- loginf("too many tries to get hello packet");
- SM_ERROR;
- }
- PUTCHAR(ENQ);
- SM_PROCEED(waitchar)
-
- SM_STATE(waitchar)
-
- c=GETCHAR(10);
- if (c == TIMEOUT) {SM_PROCEED(sendenq);}
- else if (c < 0)
- {
- SM_ERROR;
- }
- else switch (c)
- {
- case 0x1f: SM_PROCEED(getpacket); break;
- case YOOHOO: SM_PROCEED(sendenq); break;
- default: debug(10,"got '%s' waiting hello",
- printablec(c));
- SM_PROCEED(waitchar);
- break;
- }
-
- SM_STATE(getpacket)
-
- GET((char*)&hello,sizeof(hello),30);
- if (STATUS)
- {
- SM_ERROR;
- }
- lcrc=crc16((char*)hello.data,sizeof(hello.data));
- rcrc=(hello.crc[0]<<8)+hello.crc[1];
- if (lcrc != rcrc)
- {
- debug(10,"crc does not match in hello packet: %04xh/%04xh",
- rcrc,lcrc);
- SM_PROCEED(sendnak);
- }
- else {SM_PROCEED(sendack);}
-
- SM_STATE(sendnak)
-
- if (count++ > 9)
- {
- loginf("too many tries to get hello packet");
- SM_ERROR;
- }
- PUTCHAR('?');
- SM_PROCEED(waitchar);
-
- SM_STATE(sendack)
-
- PUTCHAR(ACK);
- SM_SUCCESS;
-
- SM_END
- SM_RETURN
-
-
- SM_DECL(txyoohoo,"txyoohoo")
- SM_STATES
- sendyoohoo,waitenq,sendpkt,waitchar
- SM_NAMES
- "sendyoohoo","waitenq","sendpkt","waitchar"
- SM_EDECL
-
- int c;
- int count=0;
- int startstate;
- unsigned short lcrc;
-
- if (iscaller) startstate=sendpkt;
- else startstate=sendyoohoo;
- lcrc=crc16((char*)hello.data,sizeof(hello.data));
- hello.crc[0]=lcrc>>8;
- hello.crc[1]=lcrc&0xff;
-
- SM_START(startstate)
-
- SM_STATE(sendyoohoo)
-
- PUTCHAR(YOOHOO);
- SM_PROCEED(waitenq);
-
- SM_STATE(waitenq)
-
- c=GETCHAR(10);
- if (c == TIMEOUT)
- {
- if (count++ > 9)
- {
- loginf("timeout waiting ENQ");
- SM_ERROR;
- }
- else
- {
- SM_PROCEED(sendyoohoo);
- }
- }
- else if (c < 0)
- {
- SM_ERROR;
- }
- else switch (c)
- {
- case ENQ: SM_PROCEED(sendpkt);
- case YOOHOO: SM_PROCEED(waitenq);
- default: debug(10,"got '%s' waiting hello ACK",
- printablec(c));
- SM_PROCEED(waitchar);
- break;
- }
-
- SM_STATE(sendpkt)
-
- if (count++ > 9)
- {
- loginf("too many tries to send hello packet");
- SM_ERROR;
- }
-
- PUTCHAR(0x1f);
- PUT((char*)&hello,sizeof(hello));
- if (STATUS) {SM_ERROR;}
- SM_PROCEED(waitchar);
-
- SM_STATE(waitchar)
-
- c=GETCHAR(30);
- if (c == TIMEOUT)
- {
- loginf("timeout waiting hello ACK");
- SM_ERROR;
- }
- else if (c < 0)
- {
- SM_ERROR;
- }
- else switch (c)
- {
- case ACK: SM_SUCCESS; break;
- case '?': SM_PROCEED(sendpkt); break;
- case ENQ: SM_PROCEED(sendpkt); break;
- default: debug(10,"got '%s' waiting hello ACK",
- printablec(c));
- SM_PROCEED(waitchar);
- break;
- }
-
- SM_END
- SM_RETURN
-
-
- void fillhello(capabilities,password)
- unsigned short capabilities;
- char *password;
- {
- faddr *best;
- unsigned short majver,minver;
-
- debug(10,"fillhello(0x%04hx)",capabilities);
-
- best=bestaka_s(remote->addr);
-
- sscanf(version,"%hd.%hd",&majver,&minver);
- memset(&hello,0,sizeof(hello));
- hello.data[0]='o'; /* signal */
- hello.data[2]=1; /* hello-version */
- hello.data[4]=PRODCODE; /* product */
- hello.data[6]=majver&0xff; /* prod-ver-major */
- hello.data[7]=majver>>8; /* prod-ver-major */
- hello.data[8]=minver&0xff; /* prod-ver-minor */
- hello.data[9]=minver>>8; /* prod-ver-minor */
- strncpy((char*)hello.data+10,name,59); /* name */
- strncpy((char*)hello.data+70,sysop,19); /* sysop */
- hello.data[90]=best->zone&0xff; /* zone */
- hello.data[91]=best->zone>>8; /* zone */
- hello.data[92]=best->net&0xff; /* net */
- hello.data[93]=best->net>>8; /* net */
- hello.data[94]=best->node&0xff; /* node */
- hello.data[95]=best->node>>8; /* node */
- hello.data[96]=best->point&0xff; /* point */
- hello.data[97]=best->point>>8; /* point */
-
- if (password) strncpy((char*)hello.data+98,password,8);
-
- hello.data[114]=capabilities&0xff; /* capabilities */
- hello.data[115]=capabilities>>8; /* capabilities */
- debug(10,"filled hello \"%s\"",printable((char*)hello.data,128));
- }
-
- void checkhello(void)
- {
- unsigned short i,majver,minver;
- fa_list **tmpl,*tmpn;
- faddr remaddr;
- char *prodnm;
-
- if ((hello.data[0] != 'o') ||
- (hello.data[1] != 0) ||
- (hello.data[2] != 1) ||
- (hello.data[3] != 0))
- {
- loginf("got \"%s\" instead of \"o\\000\\001\000\"",
- printable((char*)hello.data,3));
- }
- for (i=0;ftscprod[i].name;i++)
- if (ftscprod[i].code == hello.data[4]) break;
- prodnm=ftscprod[i].name;
- majver=hello.data[6]+(hello.data[7]<<8);
- minver=hello.data[8]+(hello.data[9]<<8);
- remaddr.zone=hello.data[90]+(hello.data[91]<<8);
- remaddr.net=hello.data[92]+(hello.data[93]<<8);
- remaddr.node=hello.data[94]+(hello.data[95]<<8);
- remaddr.point=hello.data[96]+(hello.data[97]<<8);
- remaddr.name=NULL;
- remaddr.domain=NULL;
- for (tmpl=&remote;*tmpl;tmpl=&((*tmpl)->next));
- if (metric(remote->addr,&remaddr) == 0)
- {
- (*tmpl)=(fa_list*)xmalloc(sizeof(fa_list));
- (*tmpl)->next=NULL;
- (*tmpl)->addr=(faddr*)xmalloc(sizeof(faddr));
- (*tmpl)->addr->zone=remaddr.zone;
- (*tmpl)->addr->net=remaddr.net;
- (*tmpl)->addr->node=remaddr.node;
- (*tmpl)->addr->point=remaddr.point;
- }
- for (tmpn=nllist;tmpn;tmpn=tmpn->next)
- if (tmpn->addr->zone == (*tmpl)->addr->zone) break;
- if (tmpn) (*tmpl)->addr->domain=xstrcpy(tmpn->addr->domain);
- else (*tmpl)->addr->domain=NULL;
- (*tmpl)->addr->name=NULL;
-
- for (tmpl=&remote;*tmpl;tmpl=&((*tmpl)->next));
- (void)nodelock((*tmpl)->addr);
- /* lock all remotes, ignore locking result */
-
- loginf("remote address: %s",ascfnode(remote->addr,0x0f));
- loginf("remote password: %s",(char*)hello.data+98);
- loginf("remote uses: %s [%02X] version %d.%d",
- prodnm?prodnm:"<unknown program>",hello.data[4],
- majver,minver);
- loginf("remote system: %s",(char*)hello.data+10);
- loginf("remote operator: %s",(char*)hello.data+70);
- remote->addr->name=xstrcpy((char*)hello.data+70);
- }
-